package com.diviner.jsontransform.service;

import com.diviner.jsontransform.enums.TitleEnum;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicInteger;

@Service
public class JsonToExcelService {
    /**
     * json转excel
     * @param json
     * @param response
     * @throws IOException
     */
    public void jsonToExcel(String json, HttpServletResponse response) throws IOException {
        //将json转换为tree
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = mapper.readTree(json);

        XSSFWorkbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("Swagger API导出Excel");
        // 添加表头
        Row headerRow = sheet.createRow(0);
        for (TitleEnum value : TitleEnum.values()) {
            headerRow.createCell(value.getCode()).setCellValue(value.getTitle());
        }
        // 行索引
        AtomicInteger rowIndex = new AtomicInteger(1);
        // 遍历 paths 中的方法
        JsonNode pathsNode = jsonNode.get("paths");
        if (pathsNode != null) {
            pathsNode.fieldNames().forEachRemaining(path -> {
                JsonNode methodsNode = pathsNode.get(path);
                methodsNode.fieldNames().forEachRemaining(method -> {
                    Row dataRow = sheet.createRow(rowIndex.getAndIncrement());
                    dataRow.createCell(TitleEnum.getCode("URL")).setCellValue(path);
                    dataRow.createCell(TitleEnum.getCode("请求方式")).setCellValue(method.toUpperCase());
                    dataRow.createCell(TitleEnum.getCode("api名称")).setCellValue(methodsNode.get(method).path("summary").asText());
                    // 获取 Description
                    String description = methodsNode.get(method).path("description").asText();
                    dataRow.createCell(TitleEnum.getCode("备注")).setCellValue(description);  // 设置 Description
                    // 获取 Tags
                    JsonNode tagsNode = methodsNode.get(method).get("tags");
                    StringBuilder tags = new StringBuilder();
                    if (tagsNode != null) {
                        tagsNode.forEach(tag -> tags.append(tag.asText()).append(", "));
                    }
                    dataRow.createCell(TitleEnum.getCode("模块")).setCellValue(tags.length() > 0 ? tags.substring(0, tags.length() - 2) : "N/A");
                    // 获取 Content-Type
                    JsonNode consumesNode = methodsNode.get(method).get("consumes");
                    StringBuilder contentType = new StringBuilder();
                    if (consumesNode != null) {
                        consumesNode.forEach(type -> contentType.append(type.asText()).append(", "));
                    }
                    dataRow.createCell(TitleEnum.getCode("content_type")).setCellValue(contentType.length() > 0 ? contentType.substring(0, contentType.length() - 2) : "N/A");
                    // 获取请求参数
                    JsonNode parametersNode = methodsNode.get(method).get("parameters");
                    StringBuilder params = new StringBuilder();
                    if (parametersNode != null) {
                        parametersNode.forEach(param -> params.append(param.path("name").asText()).append(" (").append(param.path("in").asText()).append("), "));
                    }
                    dataRow.createCell(TitleEnum.getCode("请求参数")).setCellValue(params.length() > 0 ? params.substring(0, params.length() - 2) : "N/A");
                });
            });
        }
        // 设置响应
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=api_methods.xlsx");
        workbook.write(response.getOutputStream());
        workbook.close();
    }

    /**
     * 上传txt转excel
     * @param file
     * @param response
     */
    public void uploadJsonToExcel(MultipartFile file, HttpServletResponse response) {
        String originalFilename = file.getOriginalFilename();
        if (!originalFilename.endsWith(".txt")) {
            throw new RuntimeException("文本不合法");
        }
        String s = readFile(file);
        try {
            jsonToExcel(s,response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取txt文件
     * @param file
     * @return
     */
    private String readFile(MultipartFile file) {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader reader = null;
        InputStreamReader streamReader = null;
        try {
            streamReader = new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8);
            reader = new BufferedReader(streamReader);
            String line;
            int lineCount = 0;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
                lineCount++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                reader.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            try {
                streamReader.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return stringBuilder.toString();
    }
}
